// EnableIf去往何处

enbaleif通常用于函数模板的返回类型，但是这种方法不适用于构造函数模板或转换函数模板
，因为他们没有指定的返回类型？Enableif的用法会使返回类型难以阅读

// =============================
// enable_if 在不同场景中的局限性
// =============================

1. 构造函数模板的问题
构造函数没有返回类型，因此不能使用返回类型位置的 enable_if：
template <typename T>
class MyClass {
public:
    // 错误：构造函数没有返回类型
    template <typename U>
    typename std::enable_if<std::is_convertible_v<U, T>>::type // 这里会被编译器识别为返回类型
    MyClass(U value);  // 这不能工作！
};

2. 转换函数模板的问题
转换函数的返回类型是固定的（转换目标类型），不能用于条件启用：
template <typename T>
class Wrapper {
private:
    T value;
public:
    // 错误：返回类型必须是T，不能用于enable_if
    // operator也不能有显式的返回类型
    template <typename U>
    typename std::enable_if<std::is_convertible_v<T, U>, U>::type
    operator U() const;  // 这不能工作！
};

3. 返回类型可读性问题
使用返回类型位置的enable_if确实会使函数签名难以阅读：
// 难以理解的返回类型
template <typename T, typename U>
typename std::enable_if<
    std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
    typename std::common_type<T, U>::type
>::type
add(T a, U b) {
    return a + b;
}


// ==============================
// 替代解决方案
// ==============================
1. 对于构造函数：使用额外的模板参数
template <typename T>
class MyClass {
public:
    // 使用额外的默认模板参数
    template <typename U, 
              typename = std::enable_if_t<std::is_convertible_v<U, T>>>
    MyClass(U value) : data(value) {}
    
private:
    T data;
};

2. 对于转换函数：使用额外的模板参数
template <typename T>
class Wrapper {
private:
    T value;
public:
    // 使用额外的默认模板参数
    template <typename U, 
              typename = std::enable_if_t<std::is_convertible_v<T, U>>>
    operator U() const {
        return static_cast<U>(value);
    }
};

3. 使用C++14的别名模板简化返回类型
// 使用enable_if_t简化
template <typename T, typename U>
std::enable_if_t<
    std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
    std::common_type_t<T, U>
>
add(T a, U b) {
    return a + b;
}

4. 使用C++17的if constexpr替代enable_if
// 使用if constexpr代替enable_if
template <typename T, typename U>
auto add(T a, U b) {
    if constexpr (std::is_arithmetic_v<T> && std::is_arithmetic_v<U>) {
        return a + b;
    } else {
        static_assert(always_false_v<T>, 
                     "Types must be arithmetic");
    }
}

5. 使用C++20的概念(Concepts)
// 使用概念定义约束
template <typename T, typename U>
    requires std::is_arithmetic_v<T> && std::is_arithmetic_v<U>
auto add(T a, U b) {
    return a + b;
}

// 或使用简写语法
template <std::arithmetic T, std::arithmetic U>
auto add(T a, U b) {
    return a + b;
}

6. 使用约束的auto返回类型(C++14及以后)
// 使用auto返回类型和尾置返回类型声明
template <typename T, typename U>
auto add(T a, U b) 
    -> std::enable_if_t<
        std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
        decltype(a + b)
    > 
{
    return a + b;
}